#-*-coding:utf8-*-
import simplejson
from dateutil import parser
from datetime import datetime, timedelta
from pymongo import ASCENDING, DESCENDING

from basic import MongoDBCollectionHandler
from orm import TweetStatus


class StatusCollection(MongoDBCollectionHandler):
    '''
    Class that handles tw_status collection
    It storages tweet of the users.
    '''
    collection_name = "tw_status"

    def __init__(self):
        super(StatusCollection, self).\
                __init__(StatusCollection.collection_name)
        if(self.col_handler.count() == 0):
            print "Row count is 0. It might be the first time to use " + \
                    StatusCollection.collection_name + " collection."
            self.col_handler.ensure_index([("status_id", 1)], unique=True)

    def insert(self, tweet_list_dump, api):
        '''
        Insert tweets into the collection

        @param tweet_list_dump : [string ...] : list of json_dump of tweet
        #rtype boolean
        '''

        for tweet_json in tweet_list_dump:
            tweet = simplejson.loads(tweet_json)
            screen_name = tweet["user"]["screen_name"]
            author_id = long(tweet["user"]["id"])
            status_id = long(tweet["id"])

            message = tweet["text"]
            json_dump = simplejson.dumps(tweet)

            #Mon Jun 27 19:32:19 +0000 2011
            date = parser.parse(tweet["created_at"])
            parent = tweet["in_reply_to_status_id_str"]

            document = {"screen_name": screen_name,
                        "author_id": author_id,
                        "status_id": status_id,
                        "message": message,
                        "json_dump": json_dump,
                        "api" : api,
                        "date": date,
                        "parent": parent}

            self.col_handler.insert(document)
            return True

    def get_oldest_message_id(self, screen_name=None):
        '''
        Returns oldest status id (by comparing status id) of screen_name
        When screen_name is None, it applies to all screen_names

        @param screen_name : string : user's screen name to be filtered
        @rtype long
        '''

        if(screen_name == None):
            latest_tweet = self.col_handler.find().\
                    sort("status_id", ASCENDING).limit(1)
        else:
            latest_tweet = self.col_handler.\
                    find({"screen_name": screen_name}).\
                    sort("status_id", ASCENDING).limit(1)

        if (latest_tweet.count() == 0):
            return 0

        return latest_tweet[0]["status_id"]

    def get_newest_message_id(self, screen_name=None):
        '''
        Returns newest status id (by comparing status id) of screen_name
        When screen_name is None, it applies to all screen_names

        @param screen_name : string : user's screen name to be filtered
        @rtype long
        '''

        if (screen_name == None):
            latest_tweet = self.col_handler.find().\
                    sort("status_id", DESCENDING).limit(1)
        else:
            latest_tweet = self.col_handler.\
                    find({"screen_name": screen_name}).\
                    sort("status_id", DESCENDING).limit(1)

        if (latest_tweet.count() == 0):
            return 0

        return latest_tweet[0]["status_id"]

    def get_week_ago_status(self, screen_name=None):
        '''
        Return oldest TweetStatus since 7 days of the screen_name
        If the screen name is None, it will return TweetStatus within all
        tweet status
        '''

        time_week_ago = datetime.now() - timedelta(days=30)

        if (screen_name == None):
            tweet_cursor = self.col_handler.\
                    find({"date": {"$gte": time_week_ago}}).\
                    sort("date", ASCENDING).limit(1)
        else:
            tweet_cursor = self.col_handler.\
                    find({"date": {"$gte": time_week_ago},\
                    "screen_name": screen_name})\
                    .sort("date", ASCENDING).limit(1)

        if (tweet_cursor.count() <= 0):
            return None
        else:
            return TweetStatus(tweet_cursor[0])

    def fetch_statuses(self, screen_name=None, since_id=None, max_id=None):
        '''
        Returns list of TweetStatus which applies screen_name, since_id,
        and max_id. When screen_name is None, it applies to all users.
        When since_id is None, it looks from begining of the collection.
        When max_id is None, it looks until latest of the collection.
        Return list include max_id when it is specified and exists in
        collection.

        @param screen_name : string : screen name of the user to be filtered
        @param since_id : long : status id to begin
        @param max_id : long : status id to end (included in result list
        when it exists)
        '''

        if(screen_name == None and since_id == None and max_id == None):
            tweet_cursor = self.col_handler.find()

        elif(screen_name == None and since_id == None and max_id != None):
            tweet_cursor = self.col_handler.find(\
                    {"status_id": {"$lte": max_id}})

        elif(screen_name == None and since_id != None and max_id == None):
            tweet_cursor = self.col_handler.find(
                    {"status_id": {"$gt": since_id}})

        elif(screen_name == None and since_id != None and max_id != None):
            tweet_cursor = self.col_handler.find(\
                    {"status_id": {"$gt": since_id, "$lte": max_id}})

        elif(screen_name != None and since_id == None and max_id == None):
            tweet_cursor = self.col_handler.find({"screen_name": screen_name})

        elif(screen_name != None and since_id == None and max_id != None):
            tweet_cursor = self.col_handler.find({"screen_name": screen_name, \
                    "status_id": {"$lte": max_id}})

        elif(screen_name != None and since_id != None and max_id == None):
            tweet_cursor = self.col_handler.find({"screen_name": screen_name, \
                    "status_id": {"$gt": since_id}})

        elif(screen_name != None and since_id != None and max_id != None):
            tweet_cursor = self.col_handler.find({"screen_name": screen_name, \
                    "status_id": {"$gt": since_id, "$lte": max_id}})

        tweet_cursor.sort("status_id", ASCENDING)
        tweet_list = []
        for index in range(0, tweet_cursor.count()):
            tweet_list.append(TweetStatus(tweet_cursor[index]))

        return tweet_list

if __name__ == "__main__":
    status_coll = StatusCollection()
    #print status_coll.get_week_ago_status().date
    #print status_coll.get_oldest_message_id()
    #tweet_list = status_coll.fetch_statuses(max_id=126107288510545922L)
    #for at in tweet_list:
    #    print unicode(at)
    #print len(tweet_list)
